package com.xxx.upload;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;

/**
 * @version v1.0
 * @Description:
 * @Author zhanzhongxin
 * @Date 2021/8/10 13:51
 * @Copyright 博为峰
 */
@WebServlet("/up")
public class UploadServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String path = "D:\\workspace\\upload\\2021-08-10\\";
        String fileName = "8e7602b9-0dc8-4006-bbbd-20128e5debaa_IO.jpg";
        final Path downPath = Paths.get(path + fileName);
        //创建读取文件的字节流
        final InputStream inputStream = Files.newInputStream(downPath);
        final ServletOutputStream outputStream = resp.getOutputStream();
        //设置响应头
        resp.setHeader("Content-type", getServletContext().getMimeType(fileName));
        resp.setHeader("Content-Disposition", "attachment;filename" + URLEncoder.encode(fileName, "utf-8"));
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = inputStream.read(bytes)) > 0) {
            outputStream.write(bytes, 0, len);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //上传文件的保存目录
        Path savePath = Paths.get("D:\\workspace\\upload");
        if (!Files.exists(savePath)) {
            Files.createDirectory(savePath);
        }
        //上传时生成的临时文件保存目录
        Path tempPath = Paths.get("D:\\workspace\\temp");
        if (!Files.exists(tempPath)) {
            Files.createDirectory(tempPath);
        }

        //使用Apache上传组件处理文件上传

        try {
            //1.创建DiskFileItemFactory工厂对象
            final DiskFileItemFactory factory = new DiskFileItemFactory();
            //2.设置工厂对象的缓存区大小，当上传的文件大小超过缓存大小时，就会生成一个临时文件存储到指定的临时目录中
            factory.setSizeThreshold(1024 * 1024 * 10);
            //3.设置上传时生成的临时文件的保存目录
            factory.setRepository(tempPath.toFile());
            //4.创建文件上传解析器
            final ServletFileUpload upload = new ServletFileUpload(factory);
            //5.监听文件上传进度
            upload.setProgressListener(new ProgressListener() {
                @Override
                public void update(long l, long l1, int i) {
                    System.out.println("文件大小是:" + l1 + ",以处理:" + l);
                }
            });
            //6.设置上传文件的编码
            upload.setHeaderEncoding("utf-8");
            //7.设置上传单个文件大小的最大值
            upload.setFileSizeMax(1024 * 1024 * 10);
            //8.设置上传文件的总量的最大值
            upload.setSizeMax(1024 * 1024 * 10);
            //9.使用文件解析器解析上传数据,解析结果是一个集合，集合中每一个FileItem对应form表单中的输入项
            final List<FileItem> fileItems = upload.parseRequest(req);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {
                    final String name = fileItem.getFieldName();
                    final String value = fileItem.getString("utf-8");
                    System.out.println(name + "," + value);
                } else {
                    //获取上传文件的名称
                    String fileName = fileItem.getName();
                    System.out.println("fileName = " + fileName);
                    if (fileName == null || fileName.trim().equals("")) {
                        continue;
                    }
                    //不同的浏览器提交的文件名格式不同，有的浏览器提交的文件的文件名是带有路径的
                    fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                    //获取上传的文件扩展名
                    String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
                    System.out.println("fileExtName = " + fileExtName);

                    //获取fileItem中上传文件的输入流
                    final InputStream inputStream = fileItem.getInputStream();
                    //设置本地文件保存的名称
                    final String saveFileName = UUID.randomUUID().toString() + "_" + fileName;
                    //按时间设置本地文件保存路径
                    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    String date = dateTimeFormatter.format(LocalDateTime.now());
                    final Path saveFilePath = Paths.get("D:\\workspace\\upload\\" + date);
                    if (!Files.exists(saveFilePath)) {
                        Files.createDirectory(saveFilePath);
                    }
                    //创建本地文件
                    final Path path = Paths.get(saveFilePath + "\\" + saveFileName);
                    //存储文件
                    Files.copy(inputStream, path);

                    //把上传文件相关信息插入数据库
                }
            }
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            System.out.println("上传文件大小超出最大值(10M)");
        } catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            System.out.println("上传文件的总大小超出最大值(10M)");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("上传失败");
        } finally {
        }
    }
}
